package com.tuya.smart.android.demo.base.widget.contact;

import android.widget.SectionIndexer;

import java.util.Arrays;
import java.util.List;

public class ContactsSectionIndexer implements SectionIndexer {

    private static String OTHER = "#";
    private static String[] mSections = {OTHER, "A", "B", "C", "D", "E", "F", "G", "H", "I",
            "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S",
            "T", "U", "V", "W", "X", "Y", "Z"};

    private static int OTHER_INDEX = 0; // index of other in the mSections array


    private int[] mPositions; // store the list of starting position index for each section
    // e.g. A start at index 0, B start at index 20, C start at index 41 and so on

    private int mCount; // this is the count for total number of contacts

    // Assumption: the contacts array has been sorted
    public ContactsSectionIndexer(List<ContactItemInterface> contacts) {
        mCount = contacts.size();

        initPositions(contacts);

//		for(int i = 0 ; i < mSections.length ; i++){
//			Log.i("ContactSectionIndexer", "Letter: " + mSections[i] + ", pos: " + mPositions[i] );
//		}
    }


    public String getSectionTitle(String indexableItem) {
        int sectionIndex = getSectionIndex(indexableItem);
        return mSections[sectionIndex];
    }

    // return which section this item belong to
    public int getSectionIndex(String indexableItem) {
        if (indexableItem == null) {
            return OTHER_INDEX;
        }

        indexableItem = indexableItem.trim();
        String firstLetter = OTHER;

        if (indexableItem.length() == 0) {
            return OTHER_INDEX;
        } else {
            // get the first letter
            firstLetter = String.valueOf(indexableItem.charAt(0)).toUpperCase();
        }

        int sectionCount = mSections.length;
        for (int i = 0; i < sectionCount; i++) {
            if (mSections[i].equals(firstLetter)) {
                return i;
            }
        }

        return OTHER_INDEX;

    }

    // initialize the position index
    public void initPositions(List<ContactItemInterface> contacts) {

        int sectionCount = mSections.length;
        mPositions = new int[sectionCount];

        Arrays.fill(mPositions, -1); // initialize everything to -1

        // Assumption: list of mItems have already been sorted by the prefer names
        int itemIndex = 0;

        for (ContactItemInterface contact : contacts) {

            String indexableItem = contact.getItemForIndex();
            int sectionIndex = getSectionIndex(indexableItem); // find out which section this item belong to

            if (mPositions[sectionIndex] == -1) // if not set before, then do this, otherwise just ignore
                mPositions[sectionIndex] = itemIndex;

            itemIndex++;

        }


        int lastPos = -1;

        // now loop through, for all the ones not found, set position to the one before them
        // this is to make confirm the array is sorted for binary search to work
        for (int i = 0; i < sectionCount; i++) {
            if (mPositions[i] == -1)
                mPositions[i] = lastPos;

            lastPos = mPositions[i];

        }

    }


    @Override
    public int getPositionForSection(int section) {
        if (section < 0 || section >= mSections.length) {
            return -1;
        }

        return mPositions[section];
    }

    @Override
    public int getSectionForPosition(int position) {
        if (position < 0 || position >= mCount) {
            return -1;
        }

        int index = Arrays.binarySearch(mPositions, position);

        /*
         * Consider this example: section positions are 0, 3, 5; the supplied
         * position is 4. The section corresponding to position 4 starts at
         * position 3, so the expected return value is 1. Binary search will not
         * find 4 in the array and thus will return -insertPosition-1, i.e. -3.
         * To get from that number to the expected value of 1 we need to negate
         * and subtract 2.
         */
        return index >= 0 ? index : -index - 2;
    }

    @Override
    public Object[] getSections() {
        return mSections;
    }

    // if first item in section, then return the section
    // otherwise return -1
    public boolean isFirstItemInSection(int position) { // check whether this item is the first item in section
        int section = Arrays.binarySearch(mPositions, position);
        return (section > -1);

    }


}
